﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Crm.SdkTypeProxy.Metadata;
using Microsoft.Crm.Sdk.Metadata;

namespace SalesTracker.Tools.EntityComparer.Lib
{
    public class EntityComparer
    {
        public List<EntityAttributes> CompareAttributes(MetadataService latestEnvrnmtSrv, MetadataService compareEnvrmmentSrv, string LogicalName)
        {
            var latestAttributes = GetEntityAttributes(LogicalName, latestEnvrnmtSrv).ToList<AttributeMetadata>();
            var ofdAttributes = GetEntityAttributes(LogicalName, compareEnvrmmentSrv).ToList<AttributeMetadata>();;
            List<EntityAttributes> attributesnotfound = new List<EntityAttributes>();
            foreach (AttributeMetadata attributemtdt in latestAttributes)
            { 
               
                if(!AttributeExists(attributemtdt,ofdAttributes))
                {
               
                    if(attributemtdt.IsCustomField.Value && attributemtdt.AttributeType.Value!= AttributeType.Virtual  && attributemtdt.AttributeType.Value != AttributeType.Internal)
                    {

                        attributesnotfound.Add(new EntityAttributes(attributemtdt.DisplayName, attributemtdt.LogicalName, attributemtdt.AttributeType.Value, attributemtdt));

                    }
                }
            }

            return attributesnotfound;
        }

        private bool AttributeExists(AttributeMetadata attributemtdt,List<AttributeMetadata> existingattributes)
        {
            foreach (AttributeMetadata outattributemtdt in existingattributes)
            {
                if (attributemtdt.LogicalName == outattributemtdt.LogicalName)
                {
                   return true;
                }
            }

            return false;
        }

        public List<STCrmEntity> GetAllEntities(MetadataService metadatasvc)
        {
            var entities = new List<STCrmEntity>();

            RetrieveAllEntitiesRequest allentitiesrequest = new RetrieveAllEntitiesRequest();
        
            allentitiesrequest.MetadataItems = MetadataItems.EntitiesOnly;
            
            RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)metadatasvc.Execute(allentitiesrequest);
           
            foreach (CrmMetadata metadata in response.CrmMetadata)
            {
         
            RetrieveEntityRequest req = new RetrieveEntityRequest();
            req.EntityItems = EntityItems.EntityOnly;
            req.MetadataId = metadata.MetadataId.Value;
        

            RetrieveEntityResponse resp = (RetrieveEntityResponse)metadatasvc.Execute(req);
            

            if (resp.EntityMetadata.DisplayName.UserLocLabel != null && resp.EntityMetadata.IsCustomizable.Value)
            {
                var entity = new STCrmEntity(resp.EntityMetadata.DisplayName.UserLocLabel.Label,resp.EntityMetadata.LogicalName);
                entities.Add(entity);
            }
            
            }
           
            return entities;
        }

        public AttributeMetadata[] GetEntityAttributes(string primaryField, MetadataService metadtsrv)
        {

            RetrieveEntityRequest req = new RetrieveEntityRequest();
            req.EntityItems = EntityItems.IncludeAttributes;
            req.LogicalName = primaryField;

            RetrieveEntityResponse resp = (RetrieveEntityResponse)metadtsrv.Execute(req);
            
            return resp.EntityMetadata.Attributes;
        }

        public void CreateAttributes(MetadataService OutdatedMetadataSvc, List<EntityAttributes> createattributes)
        {
            foreach (EntityAttributes attr in createattributes)
            { 
                CreateAttributeRequest req  = new CreateAttributeRequest();
                req.Attribute = attr.CrmAttribute;
                req.EntityName = attr.CrmAttribute.EntityLogicalName;
                var response = (CreateAttributeResponse)OutdatedMetadataSvc.Execute(req);
             
            }
        }
    }
}
